package io.renren.common.privacy;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Objects;

/**
 * @author 40659
 */
public class PrivacySerialize extends JsonSerializer implements ContextualSerializer {
    private PrivacyTypeEnum type;

    private Integer prefixNoMaskLen;

    private Integer suffixNoMaskLen;

    private String maskStr;

    public PrivacySerialize(PrivacyTypeEnum type, Integer prefixNoMaskLen, Integer suffixNoMaskLen, String maskStr) {

        this.type = type;
        this.prefixNoMaskLen = prefixNoMaskLen;
        this.suffixNoMaskLen = suffixNoMaskLen;
        this.maskStr = maskStr;
    }

    public PrivacySerialize() {
    }

    @Override
    public void serialize(Object obj,JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException {
        String origin = null == obj ? null : String.valueOf(obj);
        if (StringUtils.hasText(origin) && null != type) {
            switch (type) {
                case CHINESE_NAME:
                    jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
                    break;
                case ID_CARD:
                    jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
                    break;
                case FIXED_PHONE:
                    jsonGenerator.writeString(DesensitizedUtils.fixedPhone(origin));
                    break;
                case MOBILE_PHONE:
                    jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
                    break;
                case ADDRESS:
                    jsonGenerator.writeString(DesensitizedUtils.address(origin));
                    break;
                case EMAIL:
                    jsonGenerator.writeString(DesensitizedUtils.email(origin));
                    break;
                case BANK_CARD:
                    jsonGenerator.writeString(DesensitizedUtils.bankCard(origin));
                    break;
                case PASSWORD:
                    jsonGenerator.writeString(DesensitizedUtils.password(origin));
                    break;
                case KEY:
                    jsonGenerator.writeString(DesensitizedUtils.key(origin));
                    break;
                case CUSTOMER:
                    jsonGenerator.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, maskStr));
                    break;
                default:
                    throw new IllegalArgumentException("Unknow sensitive type enum " + type);
            }
        }else {
            jsonGenerator.writeString("");
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider,BeanProperty beanProperty) throws JsonMappingException {

        if (beanProperty != null) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                PrivacyEncrypt encrypt = beanProperty.getAnnotation(PrivacyEncrypt.class);
                if (encrypt == null) {
                    encrypt = beanProperty.getContextAnnotation(PrivacyEncrypt.class);
                }
                if (encrypt != null) {
                    return new PrivacySerialize(encrypt.type(), encrypt.prefixNoMaskLen(),
                            encrypt.suffixNoMaskLen(), encrypt.maskStr());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}